// magic api
import path from "path";
import { pathToFileURL } from 'url';
import fg from "fast-glob";

/**
 * 读取规则文件 - 类似vite的import.meta.glob
 * @param {String} cwd_root 需要自动读取的文件路径
 * @param {Boolean} engin 返回读取函数还是读取结果对象
 * @returns Array<{url: String, method: String, code_modules: Object | Function}>
 */
async function GlobMagicFile(cwd_root = '') {
  const ALL_METHODS = ['get', 'post', 'put', 'delete', 'head', 'options', 'patch'];
  
  let read_js_files = fg.globSync([`**/*{${ALL_METHODS.join(',')}}.js`, `!_**/*`], {
    cwd: fg.convertPathToPattern(cwd_root), // trans
    onlyFiles: true,
    ignore: ['**/node_modules/**']
  });

  let _code_res = [];
  for (let tmp of read_js_files) {
    let matches = tmp.match(/([^\.]+)\.([^\.]+)\.js$/);
    let code_file_path = path.join(cwd_root, tmp);
    let code_modules = await import(pathToFileURL(code_file_path));
    // let code_modules = () => import(pathToFileURL(code_result.code_filename));
    let _rs = {
      method: (matches[2] || '').toUpperCase(),
      code_modules,
    };
    let fun_name_matchs = (matches[1] || '').match(/\/*([^\/]+)$/);
    let fun_spacename = (matches[1] || '').replace(/\/*([^\/]+)$/, '');
    // 'index'结尾，可选直接触发
    // if (/^.+index$/.test(matches[1]))
    if (fun_name_matchs[1] === 'index') {
      _code_res.push({
        fun_spacename: fun_spacename,
        fun_name: '',
        ..._rs
      });
    }
    _code_res.push({
      fun_spacename: fun_spacename,
      fun_name: fun_name_matchs[1],
      ..._rs
    });
  }
  return _code_res;
};

/**
 * TODO
 * - 代码块的管理 : 启用(注册)、禁用、移除
 */

// 默认的配置
const def_opts = {
  uu_key: '', // 代码模块的ID，用于模块间调用或区分
  code_path: 'magic-api',
  fun_name_init: '__init__.js',
};

export default async (fastify, opts) => {
  opts = { ...def_opts, ...opts };
  const MAGIC_ROOT = path.join(process.cwd(), opts.code_path); // 项目根路径
  
  // 服务自定义初始化hook
  let _fun_init = null;
  try {
    _fun_init = await import(pathToFileURL(`${MAGIC_ROOT}/${def_opts.fun_name_init}`));
  } catch (error) {
    console.log(`Error: ${error.message}`);
  }
  if (_fun_init) {
    // 初始化程序出错需要中断server
    await (_fun_init.default || _fun_init.main)(fastify, { ...opts.initConfig });
  }
  
  // file code
  let routes = await GlobMagicFile(MAGIC_ROOT); // magic-router
  for (let rt of routes) {
    let { uri_name, url, ...apiOpts } = rt.code_modules || {};
    let _f_name = uri_name || rt.fun_name;
    let _url = `${rt.fun_spacename ? '/' + rt.fun_spacename : '' }${_f_name ? '/' + _f_name : ''}`;
    // TODO 如果存在路由，删除路由后再添加。或者覆盖、重置
    fastify.route({
      method: rt.method || 'GET',
      url: url || _url || '/',
      ...apiOpts,
      handler: apiOpts.handler || apiOpts.default || apiOpts.main || (async (req, reply) => {
        return {code: 404, msg: 'No Function.'};
      }),
    });
  }
  
  // TODO hooks 请求前、请求后 - 拦截器

};
